#    This file is part of robo-ircbot.
#
#    robo-ircbot is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    robo-ircbot is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with robo-ircbot.  If not, see <http://www.gnu.org/licenses/>.

package Robo;
use strict;
use warnings;
use Robo::IRC;
use Robo::ModuleLoader;
use Robo::Config;
use Robo::Listener;
use threads;

# Constructor
sub new
{
        my $self = { };
        
        $self->{cfg} = Robo::Config->new("robo.xml", "mods.xml");
        $self->{mod} = Robo::ModuleLoader->new($self, $self->{cfg});
        $self->{irc} = undef;
        $self->{listener} = undef;
        
        bless($self);
        return $self;
}

# Start the IRC connection.
sub start
{
        my $self = shift;
        
        $SIG{'HUP'} = sub {
                $self->reload();
        };
        
        $self->{mod}->load_modules();
        $self->{irc} = Robo::IRC->new($self, $self->{cfg}, $self->{mod});
        $self->{irc}->irc_connect();
}

# Reload configuration and modules.
sub reload
{
        my $self = shift;
        
        $self->log(":: Reloading.");
        $self->{cfg}->load_config();
        
        # Reload dynamic modules.
        $self->{mod}->reload_modules();
        
        # Kill any existing threads.
        my @threads = threads->list();
        foreach (@threads) {
                if ($_->is_running()) {
                        eval { $_->kill('KILL')->detach(); };
                        if ($@) {
                                chomp $@;
                                $self->log($@);
                        }
                } else {
                        eval { $_->detach(); };
                        if ($@) {
                                chomp $@;
                                $self->log($@);
                        }
                }
        }
        
        # Reload the Listener.
        $self->{listener}->restart();
}

# Return a module.
sub mod
{
        my ($self, $name) = @_;
        
        # Check that this module exists.
        if (!$self->{mod}->{call}->{$name}) {
                return undef;
        }
        
        # Return module.
        return $self->{mod}->{call}->{$name};
}

# Log string to file.
sub log
{
        my ($self, $msg) = @_;
        
        if ($self->{cfg}->get_cfg("log/enabled") ne "yes") { return; }
        
        open(LOGOUT, ">>".$self->{cfg}->get_cfg("log/file")) or return;
        print LOGOUT "[".localtime()."]: ".$msg."\n";
        close(LOGOUT);
}

# Clear the log file.
sub log_clear
{
        my $self = shift;
        
        if ($self->{cfg}->get_cfg("log/enabled") ne "yes") { return; }
        
        open(LOGOUT, ">".$self->{cfg}->get_cfg("log/file")) or return;
        print LOGOUT "Log started ".localtime()."\n";
        close(LOGOUT);
}

1;
